/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package grafox.Algorithms;

import grafox.Domain.GrafoX;
import grafox.Domain.VerticeX;
import java.util.Hashtable;

/**
 * Esta classe implementa o algoritmo de Busca por Profundidade em um Grafo
 * @author admindev
 */
public class DFS {
    private Hashtable<VerticeX,Long> tempoTermino;

    public Long getTempoTermino(VerticeX vertice) {
        return tempoTermino.get(vertice);
    }

    public  Long getTempoDescoberta(VerticeX vertice) {
        return tempoDescoberta.get(vertice);
    }

    public VerticeX getPredecessor(VerticeX vertice) {
        return predecessor.get(vertice);
    }
    private Hashtable<VerticeX,Long> tempoDescoberta;
    private Hashtable<VerticeX,String> cor;
    private Long tempo;
    
    private Hashtable<VerticeX,VerticeX> predecessor;
    
    private String getCor(VerticeX vertice) {

        if (this.cor == null) {
            this.cor = new Hashtable<>();
        }

        return this.cor.get(vertice);

    }
    private void setCor(VerticeX vertice, String cor) {
        if (this.cor == null) {
            this.cor = new Hashtable<>();
        }

        this.cor.put(vertice, cor);
    }
    
    
    public DFS()
    {
        tempoTermino=new Hashtable<>();
        tempoDescoberta=new Hashtable<>();
        tempo=new Long(0);
        predecessor=new Hashtable<>();
        
    }
    
    
    
    private static DFS realizarDFS(GrafoX grafo,VerticeX origem)
    {
        
        DFS dfs = new DFS();
        
        dfs.predecessor.clear();

        for (VerticeX v : grafo.getVertices()) {
            dfs.setCor(v, "branco");
        }
        
         dfs.visita(origem);
        
        for (VerticeX v : grafo.getVertices()) {

            if ("branco".equals(dfs.getCor(v))) {
                dfs.visita(v);
            }

        }

        return dfs;    
        
        
        
    }
    
     private void visita(VerticeX vertice) {

        setCor(vertice, "cinza");
        this.tempo++;
        tempoDescoberta.put(vertice, tempo);
        vertice.visit();

        for (VerticeX adj : vertice.getAdjacentes()) {

            if ("branco".equals(this.cor.get(adj))) {              
                predecessor.put(vertice, adj);
                visita(adj);
            }

        }
        setCor(vertice, "preto");
        tempo++;
        this.tempoTermino.put(vertice, tempo);
        vertice.terminate();

    }
    
}
